#include "choosefrienddialog.h"
#include "debug.h"
#include <QPushButton>
#include <QLabel>
#include <QScrollBar>
#include <QLineEdit>
#include <QPixmap>
#include <QGraphicsDropShadowEffect>
#include <QGridLayout>

#include "toast.h"
#include "model/datacenter.h"
using namespace model;

ChooseFriendDialog::ChooseFriendDialog(QWidget* parent, const QString& userId, const QString& tipLabel)
    : QDialog(parent), userId(userId)
{
    // 1. 设置窗口的基本属性
    this->setWindowTitle("选择好友");
    this->setWindowIcon(QIcon(":/resource/image/logo.png"));
    this->setFixedSize(600, 420);
    this->setAttribute(Qt::WA_DeleteOnClose);

    // 2. 创建布局管理器
    QHBoxLayout* mainLayout = new QHBoxLayout();
    mainLayout->setContentsMargins(0, 0, 0, 0);
    mainLayout->setSpacing(0);
    this->setLayout(mainLayout);

    // 3. 初始化窗口
    initLeftPanel(mainLayout);
    initRightPanel(mainLayout, tipLabel);

    // 4. 加载数据到窗口中
    initData();
}

void ChooseFriendDialog::initLeftPanel(QHBoxLayout* mainLayout)
{
    // 1. 构建左侧整体容器（灰色背景）
    QWidget* leftPanel = new QWidget();
    leftPanel->setStyleSheet("QWidget{background-color: #F7F7F7;}");
    leftPanel->setMinimumWidth(280);

    // 2. 左侧内部布局
    QVBoxLayout* leftLayout = new QVBoxLayout(leftPanel);
    leftLayout->setContentsMargins(20, 20, 20, 20);
    leftLayout->setSpacing(10);

    // 3. 搜索框
    QLineEdit* searchEdit = model::createSearchBox(35, "搜索", 12);
    leftLayout->addWidget(searchEdit);

    // 4. 联系人标题
    QLabel* contactLabel = new QLabel("联系人");
    contactLabel->setStyleSheet("font-size: 14px; padding: 10px 0;");
    contactLabel->setFixedHeight(40);
    leftLayout->addWidget(contactLabel);

    // 5. 设计联系人滚动区域
    initScrollPanel(leftLayout, totalContainer);

    // 6. 添加到主布局
    mainLayout->addWidget(leftPanel);

#if TEST_UI
    QIcon defaultAvatar(":/resource/image/kenan.png");
    for (int i = 0; i < 3; ++i) {
        addFriend(QString::number(1000 + i), defaultAvatar, "张三" + QString::number(i), false);
    }
#endif
}

void ChooseFriendDialog::initRightPanel(QHBoxLayout* mainLayout, const QString& tipLabel)
{
    // 1. 右侧整体容器（白色背景）
    QWidget* rightPanel = new QWidget();
    rightPanel->setStyleSheet("QWidget{background-color: white;}");
    rightPanel->setFixedWidth(280);

    // 2. 右侧内部布局
    QVBoxLayout* rightLayout = new QVBoxLayout(rightPanel);
    rightLayout->setContentsMargins(0, 0, 0, 0);
    rightLayout->setSpacing(0);

    // 3. 选择联系人标题
    QLabel* selectLabel = new QLabel(tipLabel);
    selectLabel->setStyleSheet(R"(
        QLabel{
           font-size: 14px;
           padding: 15px;
           border-bottom: 1px solid #EEE;
        }
    )");
    selectLabel->setFixedHeight(50);
    rightLayout->addWidget(selectLabel);

    // 4. 设计滚动区域
    initScrollPanel(rightLayout, selectedContainer);

    // 5. 按钮区域
    QWidget* buttonContainer = new QWidget();
    buttonContainer->setStyleSheet("background: white; border-top: 1px solid #EEE;");
    buttonContainer->setFixedHeight(70);

    QHBoxLayout* buttonLayout = new QHBoxLayout(buttonContainer);
    buttonLayout->setContentsMargins(20, 10, 20, 10);

    // 完成按钮
    QPushButton* okBtn = new QPushButton("完成");
    okBtn->setFixedHeight(40);
    okBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    okBtn->setStyleSheet(R"(
        QPushButton {
            background-color: #07c160;
            color: white;
            border: none;
            border-radius: 5px;
            font-size: 14px;
            font-weight: 500;
        }
        QPushButton:hover {
            background-color: #06ad56;
        }
        QPushButton:pressed {
            background-color: #059c4d;
        }
    )");

    // 取消按钮
    QPushButton* cancelBtn = new QPushButton("取消");
    cancelBtn->setFixedHeight(40);
    cancelBtn->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
    cancelBtn->setStyleSheet(R"(
        QPushButton {
            background-color: #F0F0F0;
            color: #666;
            border: none;
            border-radius: 5px;
            font-size: 14px;
        }
        QPushButton:hover {
            background-color: #E5E5E5;
        }
        QPushButton:pressed {
            background-color: #D9D9D9;
        }
    )");

    // 添加到按钮布局
    buttonLayout->addWidget(okBtn);
    buttonLayout->addSpacing(10);
    buttonLayout->addWidget(cancelBtn);

    rightLayout->addWidget(buttonContainer);

    // 6. 添加到主布局
    mainLayout->addWidget(rightPanel);

    // 7. 槽函数
    connect(okBtn, &QPushButton::clicked, this, &ChooseFriendDialog::clickOkBtn);
    connect(cancelBtn, &QPushButton::clicked, this, [=]() {
        this->close();
    });
}


void ChooseFriendDialog::initScrollPanel(QVBoxLayout *layout, QWidget *&container)
{
    // 1. 创建联系人列表容器
    container = new QWidget();
    container->setObjectName("ScrollPanel");
    container->setStyleSheet("#ScrollPanel{background-color: transparent;}");

    // 2. 创建联系人列表滚动区域对象
    QScrollArea* contactScroll = model::createScrollArea();
    layout->addWidget(contactScroll, 1); // 占据剩余空间
    contactScroll->setWidget(container);

    // 3. 联系人列表布局
    QVBoxLayout* vlayout = new QVBoxLayout();
    vlayout->setSpacing(0);
    vlayout->setContentsMargins(0, 0, 0, 0);
    vlayout->setAlignment(Qt::AlignTop);
    container->setLayout(vlayout);
    // vlayout->addStretch(); // 添加伸缩器 -- 这个是选中靠下显示的元凶
}

void ChooseFriendDialog::initData(){
    // 遍历好友列表 把好友列表中元素添加到窗口
    DataCenter* dataCenter = DataCenter::getInstance();
    QList<UserInfo>* friendList = dataCenter->getFriendList();
    if(friendList == nullptr){
        LOG() << "加载数据时发现好友列表为空!";
        return;
    }
    for(auto it = friendList->begin(); it != friendList->end(); ++it){
        if (it->userId == this->userId) {
            this->addSelectedFriend(it->userId, it->avatar, it->nickname);
            this->addFriend(it->userId, it->avatar, it->nickname, true);
        } else {
            this->addFriend(it->userId, it->avatar, it->nickname, false);
        }
    }
}


void ChooseFriendDialog::clickOkBtn(){
    // 1. 根据选中的好友列表中的元素, 得到所有的要创建群聊会话的用户 id 列表
    QList<QString> userIdList = generateMemberList();
    if (userIdList.size() < 3) {
        Toast::showMessage("群聊中的成员不足三个, 无法创建群聊");
        return;
    }

    // 2. 发送网络请求创建群聊
    DataCenter* dataCenter = DataCenter::getInstance();
    dataCenter->createGroupChatSessionAsync(userIdList);

    // 3. 关闭当前窗口
    this->close();
}

QList<QString> ChooseFriendDialog::generateMemberList(){
    QList<QString> result;
    // 1. 把自己添加到结果中
    DataCenter* dataCenter = DataCenter::getInstance();
    if (dataCenter->getMyself() == nullptr) {
        LOG() << "个人信息尚未加载!";
        return result;
    }
    result.push_back(dataCenter->getMyself()->userId);

    // 2. 遍历选中的列表
    QVBoxLayout* layout = dynamic_cast<QVBoxLayout*>(selectedContainer->layout());
    for (int i = 0; i < layout->count(); ++i) {
        auto* item = layout->itemAt(i);
        if (item == nullptr || item->widget() == nullptr) {
            continue;
        }
        auto* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
        result.push_back(chooseFriendItem->getUserId());
    }
    return result;
}

void ChooseFriendDialog::addFriend(const QString& userId, const QIcon &avatar, const QString &name, bool checked){
    ChooseFriendItem* item = new ChooseFriendItem(this, userId, avatar, name, checked);
    totalContainer->layout()->addWidget(item);
}

void ChooseFriendDialog::addSelectedFriend(const QString& userId, const QIcon &avatar, const QString &name){
    ChooseFriendItem* item = new ChooseFriendItem(this, userId, avatar, name, true);
    selectedContainer->layout()->addWidget(item);
}

void ChooseFriendDialog::deleteSelectedFriend(const QString &userId)
{
    // 遍历 selectedContainer 中的每个 Item, 对比每个 Item 里的 userId , 是否是要删除的 userId.
    QVBoxLayout* vlayout = dynamic_cast<QVBoxLayout*>(selectedContainer->layout());
    // 由于是要 "遍历" + "删除" 需要从后往前进行
    for (int i = vlayout->count() - 1; i >= 0; --i) {
        auto* item = vlayout->itemAt(i);
        if (item == nullptr || item->widget() == nullptr) {
            continue;
        }
        ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
        // 判定当前的 Item 的 userId 是否是要删除的 userId
        if (chooseFriendItem->getUserId() != userId) {
            continue;
        }
        vlayout->removeWidget(chooseFriendItem);
        // 此处直接使用 delete 可能导致程序直接崩溃. 因为 delete 该对象的时候, 该对象内部的 QCheckBox 还在使用中 (触发着信号槽呢)
        // delete chooseFriendItem;
        // 改成 deleteLater, 就相当于把 delete 操作委托给 Qt 自身来完成了. 告诉 Qt 框架说, 你要删除这个对象. 至于啥时候删除 Qt
        // 会确保在 Qt 自身用完了之后, 去真正删除.
        chooseFriendItem->deleteLater();
    }

    // 再遍历一下左侧列表, 把左侧列表中对应 item 的 checkBox 勾选状态取消掉.
    QVBoxLayout* vlayoutLeft = dynamic_cast<QVBoxLayout*>(totalContainer->layout());
    for (int i = 0; i < vlayoutLeft->count(); ++i) {
        auto* item = vlayoutLeft->itemAt(i);
        if (item == nullptr || item->widget() == nullptr) {
            continue;
        }
        ChooseFriendItem* chooseFriendItem = dynamic_cast<ChooseFriendItem*>(item->widget());
        if (chooseFriendItem->getUserId() != userId) {
            continue;
        }
        // 取消 checkBox 选中状态
        chooseFriendItem->getCheckBox()->setChecked(false);
    }
}




/*----------------------- 选择好友窗口的元素 -----------------------*/
ChooseFriendItem::ChooseFriendItem(ChooseFriendDialog* owner, const QString& userId, const QIcon& avatar, const QString& name, bool checked)
    : userId(userId)
{
    // 1. 设置控件的基本属性
    this->setFixedHeight(50);
    this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);

    // 2. 设置布局管理器
    QHBoxLayout* layout = new QHBoxLayout();
    layout->setSpacing(10);
    layout->setContentsMargins(20, 0, 20, 0);
    this->setLayout(layout);

    // 3. 创建复选框
    checkBox = new QCheckBox();
    checkBox->setChecked(checked);
    checkBox->setFixedSize(25, 25);
    QString style = R"(
        QCheckBox { background-color: transparent; }
        QCheckBox::indicator { width: 20px; height: 20px; image: url(:/resource/image/unchecked.png);}
        QCheckBox::indicator:checked { image: url(:/resource/image/checked.png);}
    )";
    checkBox->setStyleSheet(style);

    // 4. 创建头像
    avatarBtn = new QPushButton();
    avatarBtn->setFixedSize(40, 40);
    avatarBtn->setIconSize(QSize(40, 40));
    QPixmap srcAvatar = avatar.pixmap(40, 40);
    srcAvatar = model::getRoundRectPixmap(srcAvatar, QSize(40, 40), 8);
    avatarBtn->setIcon(QIcon(srcAvatar));

    // 5. 创建名字
    nameLabel = new QLabel();
    nameLabel->setText(name);
    nameLabel->setStyleSheet("QLabel {background-color: transparent;}");

    // 6. 添加上述内容到布局管理器中
    layout->addWidget(checkBox);
    layout->addWidget(avatarBtn);
    layout->addWidget(nameLabel);

    // 7. 连接信号槽
    connect(checkBox, &QCheckBox::toggled, this, [=](bool checked) {
        if (checked) {
            owner->addSelectedFriend(userId, avatar, name); // 勾选了复选框, 把当前这个 Item, 添加到右侧的已选择区域
        } else {
            owner->deleteSelectedFriend(userId); // 取消勾选
        }
    });
}


void ChooseFriendItem::paintEvent(QPaintEvent *event){
    (void) event;
    // 根据鼠标的进入状态, 来决定绘制成不同的颜色
    QPainter painter(this);
    if (isHover) {
        // 绘制成深色
        painter.fillRect(this->rect(), QColor(234, 234, 234));
    } else {
        // 绘制成浅色
        painter.fillRect(this->rect(), QColor(247, 247, 247));
    }
}

void ChooseFriendItem::enterEvent(QEnterEvent *event){
    (void) event;
    isHover = true;
    // update 相当于 "更新界面"
    this->update();
    // 或者使用下列代码
    // this->repaint();
}

void ChooseFriendItem::leaveEvent(QEvent *event){
    (void) event;
    isHover = false;
    this->update();
}

























